package operators;

import logic.Indy;
import environment.Cell;
import environment.Environment;
import environment.Environment.Destination;
import es.deusto.ingenieria.is.formulation.Operator;
import es.deusto.ingenieria.is.formulation.State;

public class Move extends Operator{

	private Destination destination;
	
	public Move(Destination destination) {
		super("Move-" + destination, 1d);
		this.destination = destination;
	}
	
	@Override
	protected boolean isApplicable(State state) {
		
		Environment environment = (Environment)state.getInformation();
		Cell indyLocation = environment.getIndy().getLocation();
		Cell cell = environment.getGrid()[indyLocation.x][indyLocation.y];
		
		switch (this.destination) {
		case UP:
			return (indyLocation.y > 0 && cell.isUp());
		case DOWN:
			return (indyLocation.y < environment.getGrid()[0].length-1 && cell.isDown());
		case LEFT:
			return (indyLocation.x > 0 && cell.isLeft());
		case RIGHT:
			return (indyLocation.x < environment.getGrid().length-1 && cell.isRight());
		}
		
		return false;
	}

	@Override
	protected State effect(State state) {
		
		Environment environment = (Environment)state.getInformation();
		Cell indyLocation = environment.getIndy().getLocation();
		Environment newEnvironment = environment.clone();
		
		switch (this.destination) {
			case UP:		
				newEnvironment.moveIndy(indyLocation.x, indyLocation.y-1);
				break;
			case DOWN:
				newEnvironment.moveIndy(indyLocation.x, indyLocation.y+1);
				break;
			case LEFT:
				newEnvironment.moveIndy(indyLocation.x-1, indyLocation.y);
				break;
			case RIGHT:
				newEnvironment.moveIndy(indyLocation.x+1, indyLocation.y);
				break;
		}
		
		newEnvironment.getIndy().increaseCost(this.getCost());
		
		return new State(newEnvironment);
	}

}
